package com.czkevin.biliwsclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.function.Consumer;

public class HTTPHelper {

    public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0";

    public static String doGet(String s_url) throws IOException {
        return doGet(s_url, null);
    }

    public static String doGet(String s_url, Map<String, String> headers) throws IOException {
        return doGet(s_url, headers, null);
    }

    public static String doGet(String s_url, Map<String, String> headers, Consumer<HttpURLConnection> httpURLConnectionConsumer) throws IOException {
        URL url = new URL(s_url);
        final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
        conn.setRequestProperty("Accept", "application/json");
        if(headers != null) {
            headers.forEach(conn::setRequestProperty);
        }
        if(httpURLConnectionConsumer != null) {
            httpURLConnectionConsumer.accept(conn);
        }
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(10000);
        InputStream in = conn.getInputStream();
        byte[] data = StreamHelper.readFully(in);
        in.close();
        conn.disconnect();
        return new String(data, StandardCharsets.UTF_8);
    }

    public static String doGetWithSession(String s_url, int room, BiliSession session) throws IOException {
        return doGet(s_url, null, (connection) -> {
            connection.setRequestProperty("origin", "https://live.bilibili.com");
            connection.setRequestProperty("accept-language", "en,zh-CN;q=0.9,zh;q=0.8");
            connection.setRequestProperty("authority", "api.live.bilibili.com");
            connection.setRequestProperty("dht", "1");
            connection.setRequestProperty("referer", String.format("https://live.bilibili.com/%d", room));
            connection.setRequestProperty("accept-language", "en,zh-CN;q=0.9,zh;q=0.8");
            try {
                connection.setRequestProperty("cookie", String.format("_uuid=%s; SESSDATA=%s; bili_jct=%s",
                    session.uuid,
                    session.session,
                    session.biliJct
                ));
            } catch (Exception ex) { ex.printStackTrace(); }
        });
    }

    public static String doPost(String s_url, String contentType, byte[] body) throws IOException {
        return doPost(s_url, contentType, body, null);
    }

    public static String doPost(String s_url, String contentType, byte[] body, Consumer<HttpURLConnection> httpURLConnectionConsumer) throws IOException {
        URL url = new URL(s_url);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Content-Type", contentType != null ? contentType : "application/x-www-form-urlencoded; charset=UTF-8");
        conn.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
        conn.setConnectTimeout(2000);
        conn.setReadTimeout(2000);
        conn.setDoOutput(true);
        conn.setDoInput(true);

        conn.setRequestProperty("authority", "api.live.bilibili.com");
        conn.setRequestProperty("dht", "1");

        if(httpURLConnectionConsumer != null) {
            httpURLConnectionConsumer.accept(conn);
        }

        OutputStream out = conn.getOutputStream();
        out.write(body);
        out.flush();
        out.close();
        InputStream in = conn.getInputStream();
        byte[] data = StreamHelper.readFully(in);
        in.close();
        conn.disconnect();
        return new String(data, StandardCharsets.UTF_8);
    }

    public static String doPostWithSession(String s_url, String contentType, byte[] body, int room, BiliSession session, Consumer<HttpURLConnection> httpURLConnectionConsumer) throws IOException {
        return doPost(s_url, contentType, body, (connection) -> {
            connection.setRequestProperty("origin", "https://live.bilibili.com");
            connection.setRequestProperty("accept-language", "en,zh-CN;q=0.9,zh;q=0.8");
            connection.setRequestProperty("authority", "api.live.bilibili.com");
            connection.setRequestProperty("dht", "1");
            connection.setRequestProperty("referer", String.format("https://live.bilibili.com/%d", room));
            connection.setRequestProperty("accept-language", "en,zh-CN;q=0.9,zh;q=0.8");
            try {
                connection.setRequestProperty("cookie", String.format("_uuid=%s; SESSDATA=%s; bili_jct=%s",
                    session.uuid,
                    session.session,
                    session.biliJct
                ));
            } catch (Exception ex) { ex.printStackTrace(); }
            if(httpURLConnectionConsumer != null) {
                httpURLConnectionConsumer.accept(connection);
            }
        });
    }

    public static String doPostForm(String s_url, Map<String, String> params, int room, BiliSession session, Consumer<HttpURLConnection> httpURLConnectionConsumer) throws IOException {
        return doPostWithSession(s_url, "application/x-www-form-urlencoded; charset=UTF-8", session.generateHttpPostFormBody(params).getBytes(StandardCharsets.UTF_8), room, session, httpURLConnectionConsumer);
    }

}
